<template>
  <div class="page">
    <div ref="cropperPage" class="cropper-page" v-show="isShow" >
      <!-- <input capture="camera"  ref="file" type="file" accept="image/*" @change="readImage"> -->
      <input ref="file"  capture="camera" type="file" accept="image/*" @change="readImage">
      <img class="cropper-img" :style="imageStyle" ref="img">
      <div ref="cropBox" class="cropper-box" @touchstart.prevent="touchStart" @touchmove.prevent="touchMove" @touchend.prevent="touchEnd">
      </div>
    </div>
    <fountain :waterHeight="'3.5rem'"></fountain>
  </div>

</template>

<script>
import lrz from 'lrz'
import fountain from '@/components/fountain'
const getDinstance = function (point0, point1) {
  return Math.sqrt(Math.pow(point0.pageY - point1.pageY, 2) + Math.pow(point0.pageX - point1.pageX, 2))
}
export default {
  name: 'imageCropper',
  components: {
    fountain
  },
  props: {
    callback: {
      type: Function,
      default () {}
    },
    base64: {
      type: String,
      default () {
        return ''
      }
    },
    cropperConfig: {
      type: Object,
      default () {
        return {
          width: 520,
          height: 1080,
          quality: 0.7,
          maxWidth: 520
        }
      }
    }
  },
  data () {
    return {
      coverHeight: 0,
      cropperHeight: 0,
      imgInitTop: 0,
      amplitude: 0,
      imageState: {
        left: 0,
        top: 0,
        scale: 1,
        width: 0,
        height: 0,
        originX: 0,
        originY: 0
      },
      distance: 0,
      imageStyle: {
        top: '0',
        transform: 'translate3d(0px, 0px, 0px) scale(1)',
        transformOrigin: 'left top'
      },
      cropBoxRect: {},
      touchPos: {
        x: 0,
        y: 0
      },
      isShow: false,
      minScale: 0,
      info: '',
      orientation: ''
    }
  },
  watch: {
    'imageState': {
      handler (val, oldVal) {
        // console.log(val)
        this.imageStyle.transform = 'translate3d(-' + val.left + 'px, -' + val.top + 'px, 0px) scale(' + val.scale + ')'
      },
      deep: true
    }
  },
  mounted () {
    if (this.base64) {
      this.checkFace(this.base64.replace(/^data:image\/\w+;base64,/, ''), () => {
        this.orientation = 1
        this.$refs.img.onload = () => {
          this.initCropper()
        }
        this.$refs.img.src = this.base64
      })
    }
  },
  methods: {
    cancel () {
      this.file = null
      this.isShow = false
    },
    checkPhoto () {
      this.$refs.file.click()
    },
    readImage ($event) {
      this.$store.commit('isLoading', true)
      var self = this
      var file = $event.target.files[0]
      lrz(file, { width: 640 })
        .then(rst => {
          self.$store.commit('base64', rst.base64)
          self.checkFace(rst.base64.replace(/^data:image\/\w+;base64,/, ''), () => {
            self.orientation = 1
            self.$refs.img.onload = () => {
              self.$store.commit('isLoading', false)
              self.initCropper()
            }
            self.$refs.img.src = rst.base64
          })
          $event.target.value = null
        })
        // .always(() => {
        //   this.$store.commit('isLoading', false)
        // })
    },
    checkFace (base64, cb) {
      // this.$store.commit('isLoading', true)
      this.$http({
        // url: `${this.$config.baseUrl}/api/api?ifname=qq.face.detect`,
        url: `${this.$config.baseUrl}/api/api?ifname=qq.face.detect.strict`,
        method: 'post',
        data: {
          // face_url: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534488788735&di=20ab9c02eea092cdaeb5f7e291ec2696&imgtype=0&src=http%3A%2F%2Fe.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2Fb151f8198618367a2e8a46ee23738bd4b31ce586.jpg'
          face_base64: base64
        }
      }).then(res => {
        if (+res.status === 1) {
          let face = res.data.face_list[0]
          // 图片分辨率不可太低
          if (res.data.image_height < 300 || res.data.image_width < 300) {
            return this.$tools.openToast({
              msg: '照片清晰度过低，请上传清晰的自拍照',
              duration: 3000
            })
          }
          // 只能一个人脸
          if (res.data.face_list.length > 1) {
            return this.$tools.openToast({
              msg: '人脸个数超过限制  请重新上传单个人脸的照片',
              duration: 3000
            })
          }
          // 人脸不能太小
          if (face.width / res.data.image_width < 0.4) {
            return this.$tools.openToast({
              msg: '该图片人脸过小，请重新上传人脸部位较大的自拍照',
              duration: 3000
            })
          }
          this.$store.commit('face', face)
          cb()
        } else {
          // let msgObj = {
          //   '16396': '图片格式非法',
          //   '16397': '图片体积过大',
          //   '16402': '图片没有人脸'
          // }
          this.$tools.closeToast()
          this.$tools.openToast({
            msg: res.message || '图片必须包含人脸且合法',
            duration: 3000
          })
        }
      })
    },
    initCropper () {
      this.isShow = true // 显示裁剪界面
      this.$nextTick(() => {
        let cropperPage = this.$refs.cropperPage
        let pageWidth = cropperPage.clientWidth
        let pageHeight = cropperPage.clientHeight
        let cropBox = this.$refs.cropBox
        let cropBoxWidth = cropBox.clientWidth
        let cropBoxHeight = cropBoxWidth * (+this.cropperConfig.height) / (+this.cropperConfig.width)
        // console.log(cropBoxWidth, cropBoxHeight, cropBoxHeight / cropBoxWidth)
        this.$refs.cropBox.style.height = cropBoxHeight + 'px'
        this.coverHeight = pageHeight - cropBoxHeight
        let cropBoxTop = this.coverHeight
        this.imageState.left = 0
        this.imageState.top = 0

        this.imageStyle.top = cropBoxTop + 'px'

        this.cropBoxRect = {
          left: 0,
          top: cropBoxTop,
          width: pageWidth,
          height: cropBoxHeight
        }
        let img = this.$refs.img
        var width = this.imageState.width = img.naturalWidth
        var height = this.imageState.height = img.naturalHeight
        // 裁剪框宽高比
        let proportion = this.cropperConfig.width / this.cropperConfig.height
        // 计算imageState
        if (width / height > proportion) {
          this.minScale = this.imageState.scale = this.cropBoxRect.height / height
          this.imageState.left = (width * this.imageState.scale - this.cropBoxRect.width) / 2
        } else {
          this.minScale = this.imageState.scale = this.cropBoxRect.width / width
          this.imageState.top = (height * this.imageState.scale - this.cropBoxRect.height) / 2
        }
      })
    },
    confirm () {
      let self = this
      let imageState = this.imageState
      let cropBoxRect = this.cropBoxRect
      console.log('this.cropBoxRect>>>', this.cropBoxRect)
      // console.log(this.imageState)
      // 导出图片的最大宽度
      let maxWidth = this.cropperConfig.maxWidth
      let scale2 = maxWidth / cropBoxRect.width

      let scale = imageState.scale * scale2
      let width = cropBoxRect.width * scale2
      let height = cropBoxRect.height * scale2
      let left = imageState.left * scale2
      let top = imageState.top * scale2
      let image = this.$refs.img
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      // ios 的照片有拍摄的角度信息 参考 http://www.bcty365.com/content-142-3055-1.html
      let orientation = this.orientation

      canvas.width = width
      canvas.height = height
      // console.log(`orientation: ${orientation} | width: ${width} | height: ${height}`)
      // console.log(left / scale, top / scale, width / scale, height / scale, 0, 0, width, height)
      ctx.drawImage(image, left / scale, top / scale, width / scale, height / scale, 0, 0, width, height)
      let dataUrl = canvas.toDataURL('image/jpeg', this.cropperConfig.quality)
      self.callback(dataUrl)
      self.isShow = false
    },
    getFocalPoint (point0, point1) {
      return {
        x: (point0.pageX + point1.pageX) / 2,
        y: (point0.pageY + point1.pageY) / 2
      }
    },
    touchStart (event) {
      var fingerCount = event.touches.length
      if (fingerCount) {
        // 记录触摸初始位置
        let touchEvent = event.touches[0]
        this.touchPos = {
          x: touchEvent.clientX,
          y: touchEvent.clientY
        }
      }
      if (fingerCount >= 2) {
        // 获取两点距离、中点位置；两点距离old/new=放大倍数；中点位置，缩放中心；
        let point0 = event.touches[0]
        let point1 = event.touches[1]
        this.distance = getDinstance(point0, point1)
        this.touchPos = this.getFocalPoint(point0, point1)
        // 设置缩放倍数，
      }
    },
    touchMove (event) {
      // 根据触摸点位移，移动图片，重置触摸点位置
      // console.log(111)
      var fingerCount = event.touches.length
      var touchEvent = event.touches[0]
      if (fingerCount === 1) {
        let distX = touchEvent.pageX - this.touchPos.x
        let distY = touchEvent.pageY - this.touchPos.y
        let newX = this.imageState.left - distX
        let newY = this.imageState.top - distY
        let scale = this.imageState.scale
        // alert(scale)
        let maxX = this.imageState.width * scale - this.cropBoxRect.width
        let maxY = this.imageState.height * scale - this.cropBoxRect.height
        this.imageState.left = newX < 0 ? 0 : (newX > maxX ? maxX : newX)
        this.imageState.top = newY < 0 ? 0 : (newY > maxY ? maxY : newY)
        this.touchPos.x = touchEvent.pageX
        this.touchPos.y = touchEvent.pageY
      } else if (fingerCount > 1) {
        let point0 = event.touches[0]
        let point1 = event.touches[1]
        let distance = getDinstance(point0, point1)
        let zoom = distance / this.distance
        let scale = zoom * this.imageState.scale
        let maxX = this.imageState.width * scale - this.cropBoxRect.width
        let maxY = this.imageState.height * scale - this.cropBoxRect.height
        let touchPos = this.getFocalPoint(point0, point1)
        let newX = zoom * (this.imageState.left + touchPos.x) - touchPos.x
        let newY = zoom * ((this.imageState.top - this.imgInitTop) + touchPos.y) - touchPos.y + this.imgInitTop
        // 限制缩放
        // 图片新位置:由中点位置确认;(新位置到中点)/(旧位置到中点)=(new scale)/(old scale)
        // newLeft - touchPos.x = (distance / this.distance) * (oldLetf - touchPos.x)
        // oldLeft = 0 - this.imageState.left
        // oldTop = imgInitTop - this.imageState.top
        this.distance = distance
        if (scale < this.minScale) {
          this.imageState.scale = this.minScale
        } else {
          this.imageState.scale = scale
          this.imageState.left = newX < 0 ? 0 : (newX > maxX ? maxX : newX)
          this.imageState.top = newY < 0 ? 0 : (newY > maxY ? maxY : newY)
        }
        this.touchPos = touchPos
      }
    },
    touchEnd (event) {
      // console.log('end')
    }
  }
}
</script>
<style lang="scss" scoped>
.page{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
}
.cropper-page{
  position:relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.cropper-box{
  position:relative;
  z-index:5;
  // border:1px dashed #FFF;
  // overflow: hidden;
  // .round{
  //   position: absolute;
  //   bottom:67.95%;
  //   margin-left:-.15rem;
  //   margin-bottom:-.15rem;
  //   left:50%;
  //   width:.3rem;
  //   height:.3rem;
  //   border:1px solid red;
  //   border-radius:50%;
  // }
}
.cropper-img{
  position: absolute;
  z-index: -1;
}
input[type="file"]{
  opacity: 0;
  position: fixed;
  top:-1000px;
  left:-1000px;
}
</style>
